<html>
<head><meta charset="utf-8"><title>stacked borrows: &quot;gap&quot; between mutable and shared refs · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html">stacked borrows: &quot;gap&quot; between mutable and shared refs</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="148119951"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148119951" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148119951">(Nov 21 2018 at 16:09)</a>:</h4>
<p>I just realized that one of these things that I "accidentally" made work, maybe shouldn't work... namely, there is a guarantee that we might want to have but currently do not have:</p>
<div class="codehilite"><pre><span></span><span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">x</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="kt">i32</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">i32</span> <span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="o">*</span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">5</span><span class="p">;</span><span class="w"></span>
<span class="w">  </span><span class="n">unknown_code</span><span class="p">(</span><span class="o">&amp;*</span><span class="n">x</span><span class="p">);</span><span class="w"></span>
<span class="w">  </span><span class="o">*</span><span class="n">x</span><span class="w"> </span><span class="c1">// must return 5</span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p><a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2015&amp;gist=22852fd1cfdd6aac92df7165c2a4f438" target="_blank" title="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2015&amp;gist=22852fd1cfdd6aac92df7165c2a4f438">Here's a counterexample</a> that is accepted by miri.<br>
The thing is that we see "creating a shared reference" first as sharing, then as freezing. Writing to this location un-freezes, but can then rely on the sharing to write. Not good.<br>
I think this would be easy to fix, but then we would have to patch libcore:</p>
<div class="codehilite"><pre><span></span><span class="k">impl</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="p">,</span><span class="w"> </span><span class="n">T</span>: <span class="o">?</span><span class="nb">Sized</span><span class="o">&gt;</span><span class="w"> </span><span class="nb">From</span><span class="o">&lt;&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">NonNull</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="cp">#[inline]</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">from</span><span class="p">(</span><span class="n">reference</span>: <span class="kp">&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Self</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">NonNull</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">pointer</span>: <span class="nc">NonZero</span><span class="p">(</span><span class="n">reference</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="n">_</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>this desugars, with coercions, to <code>reference as &amp;T as *const T</code>, so if later we do <code>as_ptr</code> on this <code>NonNull</code>, we are not allowed to write. My problem is less with ruling out this sequence of events (it seems that we really should), and more with the fact that looking at the code here, it is very non-obvious what happens. Ideally, we could tweak the coercion mechanism such that it would desugar to <code>reference as *mut T as *const T</code>, but <span class="user-mention" data-user-id="116009">@nikomatsakis</span> said they don't want to touch coercions as they are too fragile.^^</p>
<p>Cc <span class="user-mention" data-user-id="137587">@Gankro</span> <span class="user-mention" data-user-id="116009">@nikomatsakis</span></p>



<a name="148120856"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148120856" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Gankra <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148120856">(Nov 21 2018 at 16:24)</a>:</h4>
<p>thinking out loud: It <em>seems</em> like there should be a difference between creating a shared reference locally and passing a shared reference to a function</p>



<a name="148121176"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148121176" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Gankra <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148121176">(Nov 21 2018 at 16:29)</a>:</h4>
<p>or  alternatively, transiently constructing a reference to make a raw ptr shouldn't "count"?</p>



<a name="148122462"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148122462" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148122462">(Nov 21 2018 at 16:48)</a>:</h4>
<blockquote>
<p>or  alternatively, transiently constructing a reference to make a raw ptr shouldn't "count"?</p>
</blockquote>
<p>not sure how to formalize that. we cannot predict the future, when the shared ref is created</p>



<a name="148122534"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148122534" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148122534">(Nov 21 2018 at 16:49)</a>:</h4>
<blockquote>
<p>thinking out loud: It <em>seems</em> like there should be a difference between creating a shared reference locally and passing a shared reference to a function</p>
</blockquote>
<p>we <em>could</em> make this about the fn barrier, but I am not sure if we want to. I sometimes like to imagine <code>unknown_code</code> to be a hard-to-analyze block of code in the same function that does not access <code>x</code> directly (in the above example)</p>



<a name="148140202"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148140202" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148140202">(Nov 21 2018 at 22:07)</a>:</h4>
<p>Ah I remember now, just fixing <code>NonNull::from</code> is not enough... we also have</p>
<div class="codehilite"><pre><span></span><span class="w">        </span><span class="n">Drain</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="n">deque</span>: <span class="nc">NonNull</span>::<span class="n">from</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="o">*</span><span class="bp">self</span><span class="p">),</span><span class="w"></span>
<span class="w">            </span><span class="n">after_tail</span>: <span class="nc">drain_head</span><span class="p">,</span><span class="w"></span>
<span class="w">            </span><span class="n">after_head</span>: <span class="nc">head</span><span class="p">,</span><span class="w"></span>
<span class="w">            </span><span class="n">iter</span>: <span class="nc">Iter</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">                </span><span class="n">tail</span>: <span class="nc">drain_tail</span><span class="p">,</span><span class="w"></span>
<span class="w">                </span><span class="n">head</span>: <span class="nc">drain_head</span><span class="p">,</span><span class="w"></span>
<span class="w">                </span><span class="n">ring</span>: <span class="nc">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">buffer_as_mut_slice</span><span class="p">()</span><span class="w"> </span><span class="p">},</span><span class="w"></span>
<span class="w">            </span><span class="p">},</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
</pre></div>


<p>Notice how we <em>first</em> create a raw pointer from <code>self</code> (for <code>deque</code>), but <em>then</em> pass <code>self</code> to another function, which promises that function exclusive access to the given memory and invalidates every reference previously derived from <code>self</code>.</p>



<a name="148176150"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148176150" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148176150">(Nov 22 2018 at 13:47)</a>:</h4>
<p>PR to fix <code>VecDeque</code> (well, the tiny bits of it covered by miri's test suite): <a href="https://github.com/rust-lang/rust/pull/56161" target="_blank" title="https://github.com/rust-lang/rust/pull/56161">https://github.com/rust-lang/rust/pull/56161</a></p>



<a name="148176408"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148176408" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148176408">(Nov 22 2018 at 13:53)</a>:</h4>
<blockquote>
<p>Creating a NonNull&lt;T&gt; from &amp;mut T goes through &amp;T, then *const T, then NonNull&lt;T&gt;.</p>
</blockquote>
<p>Uhhhhh</p>



<a name="148176508"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148176508" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148176508">(Nov 22 2018 at 13:55)</a>:</h4>
<blockquote>
<p>VecDeque::drain creates the Drain struct by first creating a NonNull from self (which is an &amp;mut VecDeque), and then calling self.buffer_as_mut_slice(). The latter reborrows self, asserting that self is currently the unique pointer to access this VecDeque, and hence invalidating the NonNull that was created earlier. This PR fixes that by calling buffer_as_mut_slice on an &amp;mut derived from the NonNull.</p>
</blockquote>
<p>So IIUC Drain contains a <code>NonNull</code> to the <code>VecDeque</code> and a <code>&amp;mut [T]</code> to the <code>VecDeque</code> and it currently constructs both from self.</p>



<a name="148176609"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148176609" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148176609">(Nov 22 2018 at 13:56)</a>:</h4>
<p>So IIUC, a minimal version of this problem is:</p>
<div class="codehilite"><pre><span></span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Foo</span><span class="p">;</span><span class="w"></span>
<span class="n">Bar</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">   </span><span class="n">a</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">_</span><span class="p">,</span><span class="w"></span>
<span class="w">   </span><span class="n">b</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="n">x</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>?</p>



<a name="148176638"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148176638" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148176638">(Nov 22 2018 at 13:57)</a>:</h4>
<blockquote>
<p>So IIUC Drain contains a NonNull to the VecDeque and a &amp;mut [T] to the VecDeque and it currently constructs both from self.</p>
</blockquote>
<p>Yes, and it constructors the latter <em>later</em>, by calling a function which reborrows the entire <code>self</code>, which invalidates the first.</p>



<a name="148176653"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148176653" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148176653">(Nov 22 2018 at 13:57)</a>:</h4>
<p><span class="user-mention" data-user-id="132920">@gnzlbg</span> Yes. That example itself is fine, but using <code>a</code> afterwards is not</p>



<a name="148176703"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148176703" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148176703">(Nov 22 2018 at 13:58)</a>:</h4>
<p>because you created <code>b</code> as a <em>unique</em> reference to <code>x</code>, so there cannot be another one</p>



<a name="148176711"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148176711" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148176711">(Nov 22 2018 at 13:58)</a>:</h4>
<p>but <code>a</code> is a raw pointer</p>



<a name="148176723"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148176723" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148176723">(Nov 22 2018 at 13:58)</a>:</h4>
<p>I'd expect that reading through <code>a</code> is ok, but writing through it is not.</p>



<a name="148176731"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148176731" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148176731">(Nov 22 2018 at 13:58)</a>:</h4>
<p>ah no, wait, _unique_</p>



<a name="148176764"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148176764" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148176764">(Nov 22 2018 at 13:59)</a>:</h4>
<p>I find the fix of <code>NonNull</code> ok, but I find the fix of VecDeque tricky</p>



<a name="148176772"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148176772" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148176772">(Nov 22 2018 at 13:59)</a>:</h4>
<p>I would prefer if <code>ring</code> would also just be a raw pointer</p>



<a name="148176923"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148176923" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148176923">(Nov 22 2018 at 14:01)</a>:</h4>
<p>that is, i find the fact that we have to get the raw pointer for ring from the raw pointer to the <code>deque</code> tricky</p>



<a name="148176930"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148176930" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148176930">(Nov 22 2018 at 14:01)</a>:</h4>
<blockquote>
<p>I would prefer if <code>ring</code> would also just be a raw pointer</p>
</blockquote>
<p>that would be an option. Though notice that the way the code is written, we are creating new exclusive references already just to call <code>buffer_as_mut_slice</code>. So if that function returned a raw ptr, that would not change anything on its own.</p>



<a name="148177014"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148177014" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148177014">(Nov 22 2018 at 14:03)</a>:</h4>
<p>or for Iter to just contain a pointer to the <code>deque</code> instead of the slice</p>



<a name="148177025"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148177025" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148177025">(Nov 22 2018 at 14:03)</a>:</h4>
<blockquote>
<p>that is, i find the fact that we have to get the raw pointer for ring from the raw pointer to the <code>deque</code> tricky</p>
</blockquote>
<p>it's a direct consequence of the idea that <code>&amp;mut</code> is unique when being used in a reborrow-to-<code>&amp;mut</code></p>



<a name="148177120"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148177120" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148177120">(Nov 22 2018 at 14:04)</a>:</h4>
<p>but yes, mixing raw pointers and mutable references can be tricky in this model, particularily considering that <code>self</code> methods usually take references -- so mixing methods that take <code>&amp;mut self</code> and raw pointers is risky business</p>



<a name="148177125"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148177125" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148177125">(Nov 22 2018 at 14:04)</a>:</h4>
<p>Yeah the problem is that the &amp;mut used to construct the NonNull is unique, and we invalidate it by taking another &amp;mut to self in ring</p>



<a name="148177226"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148177226" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148177226">(Nov 22 2018 at 14:06)</a>:</h4>
<blockquote>
<p>or for Iter to just contain a pointer to the <code>deque</code> instead of the slice</p>
</blockquote>
<p>wouldn't that mean double indirection and inability to use the <code>(start ptr, end ptr)</code> representation of iterators (= slowdowns)?</p>



<a name="148177253"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148177253" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148177253">(Nov 22 2018 at 14:06)</a>:</h4>
<p>yeah, i think the current fix is fine</p>



<a name="148177365"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148177365" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148177365">(Nov 22 2018 at 14:09)</a>:</h4>
<p>The current <code>Iter</code> has a <code>ring: &amp;[T]</code></p>



<a name="148177379"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148177379" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148177379">(Nov 22 2018 at 14:09)</a>:</h4>
<p>why does it have to use "buffer_as_mut_slice()" ?</p>



<a name="148180222"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148180222" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148180222">(Nov 22 2018 at 15:05)</a>:</h4>
<p>Turns out just not using a mutable buffer, as suggested by <span class="user-mention" data-user-id="132920">@gnzlbg</span> , is enough :)</p>



<a name="148180753"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148180753" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148180753">(Nov 22 2018 at 15:14)</a>:</h4>
<p>And here is the second PR do deal with this strengthening of Stacked Borrows: We need to retag in the drop shims. <a href="https://github.com/rust-lang/rust/pull/56165" target="_blank" title="https://github.com/rust-lang/rust/pull/56165">https://github.com/rust-lang/rust/pull/56165</a></p>



<a name="148181417"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148181417" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148181417">(Nov 22 2018 at 15:26)</a>:</h4>
<p>With these two fixes, the strengthened model passes miri's test suite :D</p>



<a name="148181423"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%3A%20%22gap%22%20between%20mutable%20and%20shared%20refs/near/148181423" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.3A.20.22gap.22.20between.20mutable.20and.20shared.20refs.html#148181423">(Nov 22 2018 at 15:27)</a>:</h4>
<p>(for whatever that is worth^^)</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>